#include <ctype.h>
#include <iostream>
#include <fstream>

#include "../include/Symbole.h"

using namespace std;

Symbole::Symbole(string s)
{
    this->m_chaine = s;
    // attention : l'ordre des tests ci-dessous n'est pas innocent !
    if(s == "")
    {
        this->m_categorie = FINDEFICHIER;
    }
    else if(isdigit(s[0]))
    {
        this->m_categorie = ENTIER;
    }
    else if(isMotCle(s))
    {
        this->m_categorie = MOTCLE;
    }
    else if(s[0] == '"')
    {
        this->m_categorie = CHAINE;
    }
    else if(isalpha(s[0]))
    {
        this->m_categorie = VARIABLE;
    }
    else
    {
        this->m_categorie = INDEFINI;
    }
}

bool Symbole::operator == (string ch)
{
    return  this->m_chaine == ch                                     ||
            (this->m_categorie == VARIABLE     && ch == "<VARIABLE>") ||
            (this->m_categorie == ENTIER       && ch == "<ENTIER>")   ||
            (this->m_categorie == INDEFINI     && ch == "<INDEFINI>") ||
            (this->m_categorie == CHAINE       && ch == "<CHAINE>")   ||   //ajout
            (this->m_categorie == FINDEFICHIER && ch == "<FINDEFICHIER>");
}

bool Symbole::isMotCle(string s)
{
    static vector <string> motsCles; // vecteur pour stocker les mots clés du langage
    // si on n'a pas encore chargé les mots clés dans le vecteur, on le fait !
    if(!motsCles.size())
    {
        ifstream fichier(FICHIER_MOTS_CLE, ifstream::in);
        while(!fichier.eof())
        {
            string mot;
            getline(fichier, mot);
            if(mot != "")      // insertion triée de s dans le vecteur des mots clés
            {
                vector<string>::iterator it = motsCles.begin();
                while(it < motsCles.end() && *it < mot)
                {
                    it++;
                }
                if(it == motsCles.end() || *it != mot)
                {
                    motsCles.insert(it, mot);
                }
            }
        }
        fichier.close();
    }
    // on recherche  s dans le vecteur des mots clés triés
    unsigned int i;
    for(i = 0; i < motsCles.size() && motsCles[i] < s; i++) ;
    return (i < motsCles.size() && motsCles[i] == s);
}

// Attention : cette fonction (operator << ) n'est pas membre de la classe Symbole
ostream & operator << (ostream & cout, Symbole symb)
{
    cout << "Symbole de type ";
    if(symb.m_categorie == Symbole::MOTCLE)
    {
        cout << "<MOTCLE>      ";
    }
    else if(symb.m_categorie == Symbole::VARIABLE)
    {
        cout << "<VARIABLE>    ";
    }
    else if(symb.m_categorie == Symbole::ENTIER)
    {
        cout << "<ENTIER>      ";
    }
    else if(symb.m_categorie == Symbole::CHAINE)
    {
        cout << "<CHAINE>      ";    //ajout
    }
    else if(symb.m_categorie == Symbole::INDEFINI)
    {
        cout << "<INDEFINI>    ";
    }
    else if(symb.m_categorie == Symbole::FINDEFICHIER)
    {
        cout << "<FINDEFICHIER>";
    }
    cout << " : \"" << symb.m_chaine << "\"" ;
    return cout;
}
